﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using PdfSharp.Drawing;
using System.Globalization;
using PdfSharp.Pdf;
using System.Threading;

namespace VAdvantage.Print
{
    public class TextLayout
    {
        private double advance;
        private double ascent;
        private double descent;
        private double leading;
        private double height;
        private string fullText;
        private string trimText;

        private XFontFamily layout;
        private XFont font;
        private XColor stringColor;

        TextRenderer render = new TextRenderer();

        public TextLayout()
        {

        }

        public XFont GetFont()
        {
            return font;
        }

        public TextLayout(string sb, int start, int limit, XFont stringXFont, XColor _stringColor)
        {
            font = stringXFont;
            stringColor = _stringColor;
            layout = font.FontFamily;
            fullText = sb;
            if (fullText.Length > start)
                trimText = sb.Substring(start, limit - start);


            GetGraphicLayout(sb, font);
        }

        public static char DONE = '\uFFFF';

            public TextLayout(AttributedCharacterIterator text)
        {
            fullText = text.GetText();  
            trimText = fullText;
            font = text.GetFont();
            layout = font.FontFamily;
            stringColor = text.GetColor();

            int start = text.GetBeginIndex();
            int limit = text.GetEndIndex();
            if (start == limit)
            {
                throw new ArgumentException("Zero length iterator passed to TextLayout constructor.");
            }

            int len = limit - start;
            text.First();
            char[] chars = new char[len];
            int n = 0;
            for (char c = text.First(); c != DONE; c = text.Next())
            {
                chars[n++] = c;
            }
            GetGraphicLayout(fullText, text.GetFont());
        }

        public TextLayout(string stringData, XFont font)
        {
            GetGraphicLayout(stringData, font);
        }

        TextBlock textBlock = null;
        private XSize GetFontSize(String stringText, XFont font)
        {
            textBlock = new TextBlock();
            textBlock.Text = stringText;
            textBlock.FontFamily = new FontFamily(font.Name);
            textBlock.FontSize = font.Size;
            Size actualSize = new Size(textBlock.ActualWidth, textBlock.ActualHeight);

            XSize size = new XSize(actualSize.Width, actualSize.Height);
            return size;
        }

        bool iscompleted = false;
        XSize size;

        private void GetGraphicLayout(string stringData, XFont font)
        {
            bool b = System.Windows.Deployment.Current.Dispatcher.CheckAccess();

            //if (b)
            //    size = GetFontSize(stringData, font);
            //else
            //{
            //    System.Windows.Deployment.Current.Dispatcher.BeginInvoke(delegate
            //    {
            //        size = GetFontSize(stringData, font);
            //        iscompleted = true;
            //    });

            //    while (!iscompleted)
            //    {
            //        Thread.Sleep(10);
            //    }
            //}

            //iscompleted = false;
            size = render.MeasureText(stringData, font);
            advance = size.Width;
            //advance = render.MeasureText(stringData, font);

            //XFontFamily layout = new XFontFamily(System.Drawing.Text.GenericXFontFamilies.SansSerif);
            double lineSpace = font.GetHeight();
            int cellSpace = font.FontFamily.GetLineSpacing(font.Style);
            int cellAscent = font.FontFamily.GetCellAscent(font.Style);
            int cellDescent = font.FontFamily.GetCellDescent(font.Style);
            int cellLeading = cellSpace - cellAscent - cellDescent;

            // Get effective ascent
            ascent = lineSpace * cellAscent / cellSpace;
            // Get effective descent
            descent = lineSpace * cellDescent / cellSpace;
            // Get effective leading
            if (cellLeading > 0)
                leading = lineSpace * cellLeading / cellSpace;
            //leading = lineSpacingInDU * (font.Size / emSizeInDU);
            height = size.Height + leading;
        }


        public void Draw(PdfSharp.Drawing.XGraphics g2, double x, double y)
        {
            if (g2 == null)
            {
                throw new ArgumentException("Null Graphics2D passed to TextLayout.draw()");
            }

            g2.DrawString(trimText, GetXFont(), new XSolidBrush(stringColor), x, y);
        }


        public void Draw(Canvas g2, double x, double y)
        {
            if (g2 == null)
            {
                throw new ArgumentException("Null Graphics2D passed to TextLayout.draw()");
            }

            DrawString(g2, trimText, GetXFont(), x, y);
        }

        public XFont GetXFont()
        {
            return font;
        }

        public double GetAscent()
        {
            return ascent;
        }

        public double GetDescent()
        {
            return descent;
        }

        public double GetLeading()
        {
            return leading;
        }

        public double GetAdvance()
        {
            return advance;
        }

        public double GetHeight()
        {
            return height;
        }

        public bool IsLeftToRight()
        {
            return true;
        }


        public void DrawString(Canvas can, TextBlock text, string msg, double fontSize, string fontName, double xPen, double yPen)
        {
            text = new TextBlock();
            text.Text = msg;
            text.FontSize = fontSize - 1;
            text.FontFamily = new FontFamily(fontName);
            text.Margin = new Thickness(xPen, yPen, 0, 0);
            can.Children.Add(text);
        }

        public void DrawString(Canvas can, TextBlock text, string msg, XFont font, double xPen, double yPen)
        {
            text = new TextBlock();
            text.Text = msg;
            text.FontSize = font.Size -1;

            if(font.Bold)
                text.FontWeight = FontWeights.Bold;

            text.FontFamily = new FontFamily(font.Name);
            text.Margin = new Thickness(xPen, yPen, 0, 0);
            can.Children.Add(text);
     
        }

        public void DrawString(Canvas can, string msg, XFont font, double xPen, double yPen)
        {
            var text = new TextBlock();
            text.Text = msg;
            text.FontSize = font.Size - 1;

            if (font.Bold)
                text.FontWeight = FontWeights.Bold;

            text.FontFamily = new FontFamily(font.Name);
            text.Margin = new Thickness(xPen, yPen, 0, 0);
            can.Children.Add(text);
        }
    }

}
